package com.spring.rpc;

import com.spring.annotation.RpcAnnotation;
import com.spring.registry.IRegisterCenter;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import java.util.HashMap;
import java.util.Map;

/**
 * @描述:RPC服务
 * @作者:Marks
 * @日期:23:05 2018-10-15
 * @版权:
 */
public class RpcServer {

    //注册中心
    private IRegisterCenter registerCenter;
    //服务地址
    private String serviceAddress;
    //绑定服务Map
    private Map<String, Object> handlerMap = new HashMap<>();

    public RpcServer(IRegisterCenter registerCenter, String serviceAddress) {
        this.registerCenter = registerCenter;
        this.serviceAddress = serviceAddress;
    }

    //发布服务和监听端口
    public void publisher() {
        //1.服务发布
        for (String serviceName : handlerMap.keySet()) {
            //注册服务名称和服务地址
            this.registerCenter.register(serviceName, serviceAddress);
        }
        try {
            //2.启动一个监听（netty）
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            //启动netty服务
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup);
            bootstrap.channel(NioServerSocketChannel.class);

            bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {

                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    //业务代码
                    ChannelPipeline pipeline = socketChannel.pipeline();
                    pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 0));
                    pipeline.addLast(new RpcServerHandler());
                }
            }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
            //通过netty监听 8080
            String[] addrs = serviceAddress.split(":");
            String ip = addrs[0];
            int port = Integer.parseInt(addrs[1]);

            ChannelFuture future = bootstrap.bind(ip, port).sync();

            System.out.println("netty服务启动成功，等待客户端的连接：");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //绑定服务(n个子类对象的示例)
    public void bind(Object... services) {
        for (Object service : services) {
            //注解
            RpcAnnotation annotation = service.getClass().getAnnotation(RpcAnnotation.class);
            String serviceName = annotation.value().getName();
            handlerMap.put(serviceName, service);
        }
    }

}

